/*
 * Copyright 1999-2018 Alibaba Group Holding Ltd.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.alibaba.nacos.api.naming;

import com.alibaba.nacos.api.exception.NacosException;
import com.alibaba.nacos.api.naming.listener.EventListener;
import com.alibaba.nacos.api.naming.pojo.Instance;
import com.alibaba.nacos.api.naming.pojo.ListView;
import com.alibaba.nacos.api.naming.pojo.ServiceInfo;
import com.alibaba.nacos.api.selector.AbstractSelector;

import java.util.List;

/**
 * 名称服务接口.
 *
 * @author nkorange
 */
public interface NamingService {

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param ip          实例ip
     * @param port        实例端口
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, String ip, int port) throws NacosException;

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param ip          实例ip
     * @param port        实例端口
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, String groupName, String ip, int port) throws NacosException;

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param ip          实例ip
     * @param port        实例端口
     * @param clusterName 集群名称
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param ip          实例ip
     * @param port        实例端口
     * @param clusterName 集群名称
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException;

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param instance    待注册的实例
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, Instance instance) throws NacosException;

    /**
     * 注册服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param instance    待注册的实例
     * @throws NacosException nacos exception
     */
    void registerInstance(String serviceName, String groupName, Instance instance) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param ip          实例ip
     * @param port        实例端口
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, String ip, int port) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param ip          实例ip
     * @param port        实例端口
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, String groupName, String ip, int port) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param ip          实例ip
     * @param port        实例端口
     * @param clusterName 集群名称
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, String ip, int port, String clusterName) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param ip          实例ip
     * @param port        实例端口
     * @param clusterName 集群名称
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, String groupName, String ip, int port, String clusterName) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param instance    待注销的实例
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, Instance instance) throws NacosException;

    /**
     * 注销服务实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param instance    待注销的实例
     * @throws NacosException nacos exception
     */
    void deregisterInstance(String serviceName, String groupName, Instance instance) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, String groupName) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, String groupName, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, List<String> clusters) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的所有实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> getAllInstances(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称.
     * @param healthy     健康/不健康实例标记
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, boolean healthy) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param healthy     健康/不健康实例标记
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, String groupName, boolean healthy) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param healthy     健康/不健康实例标记
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, boolean healthy, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param healthy     健康/不健康实例标记
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, String groupName, boolean healthy, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param healthy     健康/不健康实例标记
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param healthy     健康/不健康实例标记
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param healthy     健康/不健康实例标记
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException;

    /**
     * 获取某个服务的指定实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param healthy     健康/不健康实例标记
     * @param subscribe   是否订阅服务
     * @return 实例列表
     * @throws NacosException nacos exception
     */
    List<Instance> selectInstances(String serviceName, String groupName, List<String> clusters, boolean healthy, boolean subscribe) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, String groupName) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param subscribe   是否订阅服务
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, boolean subscribe) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param subscribe   是否订阅服务
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, String groupName, boolean subscribe) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, List<String> clusters) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param subscribe   是否订阅服务
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, List<String> clusters, boolean subscribe) throws NacosException;

    /**
     * 使用预定义的负载均衡策略获取某个服务的一个健康实例.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param subscribe   是否订阅服务
     * @return 符合条件的实例
     * @throws NacosException nacos exception
     */
    Instance selectOneHealthyInstance(String serviceName, String groupName, List<String> clusters, boolean subscribe) throws NacosException;

    /**
     * 订阅服务.
     *
     * @param serviceName 服务名称
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void subscribe(String serviceName, EventListener listener) throws NacosException;

    /**
     * 订阅服务.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void subscribe(String serviceName, String groupName, EventListener listener) throws NacosException;

    /**
     * 订阅服务.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void subscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;

    /**
     * 订阅服务.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void subscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException;

    /**
     * 取消订阅服务.
     *
     * @param serviceName 服务名称
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void unsubscribe(String serviceName, EventListener listener) throws NacosException;

    /**
     * 取消订阅服务.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void unsubscribe(String serviceName, String groupName, EventListener listener) throws NacosException;

    /**
     * 取消订阅服务.
     *
     * @param serviceName 服务名称
     * @param clusters    集群列表
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void unsubscribe(String serviceName, List<String> clusters, EventListener listener) throws NacosException;

    /**
     * 取消订阅服务.
     *
     * @param serviceName 服务名称
     * @param groupName   服务分组
     * @param clusters    集群列表
     * @param listener    事件监听
     * @throws NacosException nacos exception
     */
    void unsubscribe(String serviceName, String groupName, List<String> clusters, EventListener listener) throws NacosException;

    /**
     * 获取服务器所有服务名称.
     *
     * @param pageNo   页码
     * @param pageSize 每页条数
     * @return 服务名称列表
     * @throws NacosException nacos exception
     */
    ListView<String> getServicesOfServer(int pageNo, int pageSize) throws NacosException;

    /**
     * 获取服务器所有服务名称.
     *
     * @param pageNo    页码
     * @param pageSize  每页条数
     * @param groupName 分组名称
     * @return 服务名称列表
     * @throws NacosException nacos exception
     */
    ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName) throws NacosException;

    /**
     * 通过选择器获取服务器符合条件的所有服务名称.
     *
     * @param pageNo   页码
     * @param pageSize 每页条数
     * @param selector 选择器
     * @return 服务名称列表
     * @throws NacosException nacos exception
     * @since 0.7.0
     */
    ListView<String> getServicesOfServer(int pageNo, int pageSize, AbstractSelector selector) throws NacosException;

    /**
     * 通过选择器获取服务器符合条件的所有服务名称.
     *
     * @param pageNo    页码
     * @param pageSize  每页条数
     * @param groupName 分组名称
     * @param selector  选择器
     * @return 服务名称列表
     * @throws NacosException nacos exception
     */
    ListView<String> getServicesOfServer(int pageNo, int pageSize, String groupName, AbstractSelector selector) throws NacosException;

    /**
     * 获取当前客户端所有的订阅服务.
     *
     * @return 所有的订阅服务列表
     * @throws NacosException nacos exception
     */
    List<ServiceInfo> getSubscribeServices() throws NacosException;

    /**
     * 获取服务器健康状况.
     *
     * @return 服务器的健康状态
     */
    String getServerStatus();

    /**
     * 关闭服务.
     *
     * @throws NacosException exception.
     */
    void shutDown() throws NacosException;
}
